//暴力 30%point
#include<bits/stdc++.h>
using namespace std;

const int MAX_NM = 2000+5;
int p[MAX_NM][MAX_NM];
int n,m;
int countPoint(const int x,const int y,const int n,const int m);
int ans=0;

int main(int argc,char *argv[]){
    #ifdef OITEST
        #define ASEQ(a,b){if((a)!=(b)){cerr<<"assert eq failed :"<<endl<<#a<<":"<<(a)<<endl<<#b<<":"<<(b)<<endl;exit(1);}}
        #define ASNE(a,b){if((a)==(b)){cerr<<"assert not eq failed :"<<endl<<#a<<":"<<(a)<<endl<<#b<<":"<<(b)<<endl;exit(1);}}
        ASEQ(argc,3)
        ifstream ifile(argv[1]);
        ASEQ(ifile.is_open(),true)
        ifstream afile(argv[2]);
        ASEQ(afile.is_open(),true)
        #define cin ifile
    #endif
    
    cin>>n>>m;

    for(int i=1;i<=n;i++){
        string s;
        cin>>s;
        for(int j=1;j<=m;j++){
            p[i][j]=s[j-1];
        }
    }
    for(int i=1;i<n;i++){
        for(int j=1;j<m;j++){
            ans+=countPoint(i, j, n, m);
        }
    }
    cout<<ans<<endl;
    #ifdef OITEST
        int cans;
        afile>>cans;
        ASEQ(ans,cans)
    #endif
}

int countPoint(const int x,const int y,const int n,const int m){
    int ans=0;
    for(int i=x+1;i<=n;i++){
        for(int j=y+1;j<=m;j++){
            if(p[i][j]!=p[x][y]){
                break;
            }
            for(int k=i;k>=x;k--){
                if(p[k][j]!=p[x][y]){
                    goto endOfj;
                }
            }
            for(int k=j;k>=y;k--){
                if(p[x][k]!=p[x][y]){
                    goto endOfj;
                }
            }
            for(int k=j;k>=y;k--){
                if(p[i][k]!=p[x][y]){
                    goto endOfj;
                }
            }
            for(int k=i;k>=x;k--){
                if(p[k][y]!=p[x][y]){
                    goto endOfj;
                }
            }
            ans++;
            endOfj:;
        }
    }
    return ans;
}
